#include <stdio.h>
#include <stdlib.h>
#include <string.h> 
#include <getopt.h>
#include "ko-fbd.h"
#include "ko-io.h"

extern double rk_error;
void
usage(void) 
{
  int i,j;
  int M=3;
  fprintf(stderr,"usage:\n");
#ifndef _TEST_MAIN
  fprintf(stderr,"./a.out [options] [--1|--2] [");
  for (i=1; i<=M; i++){
    for (j=i; j<=M; j++)
      fprintf(stderr,"x%d%d ",i,j);
    fprintf(stderr,"... ");
  }
  fprintf(stderr,"... ");

  for (i=1; i<=M; i++) fprintf(stderr,"y%d ",i);
  fprintf(stderr,"... ]\n");
#endif
}

void print_help(void)
{
  FILE *fp;

  fp = fopen("ko-fbd-man.txt", "r");
  if(!fp){
    fprintf(stderr, "ko-fbd-man.txt is not exist.\n");
    exit(EXIT_FAILURE);
  }
  char s[500];
  while(fgets(s, 500, fp))
    fprintf(stderr,"%s", s);

  fclose(fp);  
}

int main(int argc, char *argv[])
{
  int i,j,M;
  char fname[1024] = "";
  double **X, *Xy, *Y;

  int c;
  int digit_optind = 0;
  const char *opt_name;

#ifdef _TEST_MAIN
  for(i=0; i<argc; i++)
    printf("%s ", argv[i]);
  printf("\n");
#endif

  while (1) {
    int option_index = 0;
    static int flagTwo = 0;
    static struct option long_options[] = {
      {"1", 0, 0, 0},             /* 0 */
      {"2", 0, 0, 0},             /* 1 */
      {"help", 0, 0, 'h'},        /* 2 */
      {"verbose", 2, 0, 0},       /* 3 */
      {"confidence", 2, 0, 'c'},  /* 4 */
      {"file", 1, 0, 'f'},        /* 5 */
      {"time", 0, 0, 0},          /* 6 */
      {"diag", 0, 0, 0},          /* 7 */
      {"rkerror", 1, 0, 0},       /* 8 */
      {0,0,0,0}
    };

    c = getopt_long(argc, argv, "c::f:h",
		    long_options, &option_index);
  
    if (c == -1)
      break;
    
    switch (c) {
    case 0: /* long option */
      switch(option_index){
      case 0:  /* option "--1" */
		Two = 0.5;
		if(flagTwo){
		  fprintf(stderr, "conflicting options --1 and --2\n");
		  exit(EXIT_FAILURE);
		}
		flagTwo = 1;
		break;
      case 1: /* option "--2" */
		Two = 1.0;
		if(flagTwo){
		  fprintf(stderr, "conflicting options --1 and --2\n");
		  exit(EXIT_FAILURE);
		}
		flagTwo = 1;
		break;
      case 3: /* option "--verbose" */
		flag_verbose = 1;
		if(optarg)
		  sscanf(optarg, "%d",&flag_verbose);
		if(flag_verbose <1){
		  fprintf(stderr, "argument of option --verbose must be positive integer.\n");
		  exit(EXIT_FAILURE);
		}
		break;
      case 6: /* option "--time" */
		flag_time = 1;
		break;
      case 7: /* option "--diag" */
		flag_diag = 1;
		break;
      case 8: /* option "--rkerror" */
		sscanf(optarg, "%lg",&rk_error);
		printf("rk_error=%g\n", rk_error);
		break;
      default:
		fprintf(stderr,"Error:unknown option\n");
		exit(EXIT_FAILURE);
		break;
      }
      break;            
    case 'c': /* "-c" or "--confidence" */
      flag_confidence = 1;
      if(optarg)
		sscanf(optarg, "%lg",&eps_pert);
      break;
      
    case 'f': /* "-f" or "--file" */
      strcpy(fname, optarg);
      break;
    case 'h':/* "-h" or "--help" */
      usage();
      print_help();
      exit(EXIT_SUCCESS);
      break;
    case '?':
      usage();
      exit(EXIT_FAILURE);      
      break;
      
    default:
      printf("?? getopt returned character code 0%o ??\n", c);
    }
  }

  if(*fname)
    dim = input_from_file(fname,&X,&Y);
  else
    dim = input_from_command(argc, argv, optind,&X,&Y);

  if(dim < 0){
    fprintf(stderr,"argument mismatch!\n");     usage();    return(-1);
  }
  M = dim+1;

  printf("dim: %d\n",dim); /* printing input data */
  printf("input matrix and vector:\n");
  for (i=0; i<M; i++) {
    for(j=0; j<M; j++)
      printf("%lf ",X[i][j]);
    printf(":%lf\n", Y[i]);
  }

#ifndef _TEST_IO
  double *f = ko_fbd(X, Y);
  if(!flag_confidence){
	printf("result:\n");
	if(flag_verbose)
	  for(i=0; i<2*dim+2; i++)
		printf("f[%d]=%g\n", i, f[i]);
	else
	  printf("\t%g\n", f[0]);
  }
  free(f);
#endif

  free_xy(X,Y);
  exit(EXIT_SUCCESS);
}

